/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.openide.execution; import java.text.Format; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.openide.util.NbBundle; /** Encapsulates start information for a process. It allows the user to * specify the process name to execute and arguments to provide. The progammer * then uses method exec to start the process and can pass additional format that * will be applied to arguments. * <P> * This allows to define arguments in format -user {USER_NAME} -do {ACTION} and then * use MapFormat with defined values for USER_NAME and ACTION that will be substitued * by into the arguments. * * @author Ian Formanek, Jaroslav Tulach */ public final class NbProcessDescriptor extends Object implements java.io.Serializable { /** A JDK 1.1 serial version UID */ static final long serialVersionUID = -4535211234565221486L; /** The name of the executable to run */ private String processName; /** argument format */ private String arguments; /** info about format of the arguments */ private String info; /** Create a new descriptor for the specified process, classpath switch, and classpath. * @param processName the name of the executable to run * @param argument string for formating of arguments */ public NbProcessDescriptor(String processName, String arguments) { this (processName, arguments, null); } /** Create a new descriptor for the specified process, classpath switch, and classpath. * @param processName the name of the executable to run * @param argument string for formating of arguments * @param info info how to format the arguments (human-readable string) */ public NbProcessDescriptor(String processName, String arguments, String info) { this.processName = processName; this.arguments = arguments; this.info = info; } /** Get the name of the executable to run. * @return the name */ public String getProcessName () { return processName; } /** Getter the execution arguments of the process. * @return the switch that the executable uses for passing the classpath as its command-line parameter */ public String getArguments () { return arguments; } /** Getter for the human readable info about the arguments. * @return the info string or null */ public String getInfo () { return info; } /* JST: Commented out, should not be needed. * * Get the command string and arguments from the supplied process name. * Normally the process name will be the actual name of the process executable, * in which case this method will just return that name by itself. * However, {@link org.openide.util.Utilities#parseParameters} is used * to break apart the string into tokens, so that users may: * <ul> * <li>Include command names with embedded spaces, such as <code>c:\Program Files\jdk\bin\javac</code>. * <li>Include extra command arguments, such as <code>-Dname=value</code>. * <li>Do anything else which might require unusual characters or processing. For example: * <p><code><pre> * "c:\program files\jdk\bin\java" -Dmessage="Hello /\\/\\ there!" -Xmx128m * </pre></code> * <p>This example would create the following executable name and arguments: * <ol> * <li> <code>c:\program files\jdk\bin\java</code> * <li> <code>-Dmessage=Hello /\/\ there!</code> * <li> <code>-Xmx128m</code> * </ol> * Note that the command string does not escape its backslashes--under the assumption * that Windows users will not think to do this, meaningless escapes are just left * as backslashes plus following character. * </ul> * <em>Caveat</em>: even after parsing, Windows programs (such as the Java launcher) * may not fully honor certain * characters, such as quotes, in command names or arguments. This is because programs * under Windows frequently perform their own parsing and unescaping (since the shell * cannot be relied on to do this). On Unix, this problem should not occur. * @return a list of the command name itself and any arguments, unescaped * @see Runtime#exec(String[]) * public String[] getProcessArgs() { if (processArguments == null) { processArguments = parseArguments(processName); } return (String[]) processArguments.clone(); } */ /** Executes the process with arguments formatted by the provided * format. Also the envp properties are passed to the executed process, * and a working directory may be supplied (this requires JDK 1.3 to * work correctly). * * @param format format to be aplied to arguments suplied by user * @param envp list of properties to be applied to the process, or <code>null</code> to leave unspecified * @param cwd the working directory to use, or <code>null</code> if this should not be specified * @return handle to executed process. * @exception IOException if the start of the process fails, or if setting the working directory is not supported */ public Process exec (Format format, String[] envp, File cwd) throws IOException { String stringArgs = format == null ? arguments : format.format (arguments); String[] args = parseArguments (stringArgs); // copy the call string String[] call = new String[args.length + 1]; call[0] = format.format(processName); System.arraycopy (args, 0, call, 1, args.length); /* System.out.println("Executing: "); for (int i = 0; i < call.length; i++) { System.out.println(" " + i + ". = " + call[i]); } */ if (cwd == null) { if (envp == null) { return Runtime.getRuntime ().exec (call); } else { return Runtime.getRuntime ().exec (call, envp); } } else { // Must use introspection so this code is safe on 1.2. try { Method m = Runtime.class.getMethod ("exec", new Class[] { String[].class, String[].class, File.class }); // NOI18N return (Process) m.invoke (Runtime.getRuntime (), new Object[] { call, envp, cwd }); } catch (NoSuchMethodException nsme) { throw new IOException (NbBundle.getBundle (NbProcessDescriptor.class).getString ("EXC_no_JDK13_exec")); } catch (InvocationTargetException ite) { Throwable t = ite.getTargetException (); if (t instanceof ThreadDeath) { throw (ThreadDeath) t; } else if (t instanceof IOException) { throw (IOException) t; } else { if (Boolean.getBoolean ("netbeans.debug.exceptions")) // NOI18N t.printStackTrace (); throw new IOException (t.toString ()); } } catch (Exception e) { if (Boolean.getBoolean ("netbeans.debug.exceptions")) // NOI18N e.printStackTrace (); throw new IOException (e.toString ()); } } } /** Executes the process with arguments formatted by the provided * format. Also the envp properties are passed to the executed process. * * @param format format to be aplied to arguments suplied by user * @param envp list of properties to be applied to the process, or <code>null</code> to leave unspecified * @return handle to executed process. * @exception IOException if the start of the process fails */ public Process exec (Format format, String[] envp) throws IOException { return exec (format, envp, null); } /** Executes the process with arguments formatted by the provided * format. * * @param format format to be aplied to arguments suplied by user * @return handle to executed process. * @exception IOException if the start of the process fails */ public Process exec (Format format) throws IOException { return exec (format, null); } /** Executes the process with arguments provided in constructor. * * @return handle to executed process. * @exception IOException if the start of the process fails */ public Process exec () throws IOException { return exec (null, null); } /* hashCode */ public int hashCode() { return processName.hashCode() + arguments.hashCode (); } /* equals */ public boolean equals(Object o) { if (! (o instanceof NbProcessDescriptor)) return false; NbProcessDescriptor him = (NbProcessDescriptor) o; return processName.equals(him.processName) && arguments.equals(him.arguments); } /** Parses given string to an array of arguments. * @param sargs is tokenized by spaces unless a space is part of "" token * @return tokenized string */ private static String[] parseArguments(String sargs) { return org.openide.util.Utilities.parseParameters(sargs); } } /* * Log * 21 src-jtulach1.20 1/12/00 Ian Formanek NOI18N * 20 src-jtulach1.19 12/21/99 Jesse Glick External executors can * set envvars and (on 1.3) cwd. * 19 src-jtulach1.18 10/22/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 18 src-jtulach1.17 6/8/99 Ian Formanek ---- Package Change To * org.openide ---- * 17 src-jtulach1.16 6/8/99 Petr Hamernik process name is formated * too (using the same Format like arguments) * 16 src-jtulach1.15 5/31/99 Jaroslav Tulach External Execution & * Compilation * 15 src-jtulach1.14 5/18/99 Petr Hamernik frixed bug #1638 once * more * 14 src-jtulach1.13 5/18/99 Ian Formanek Fixed spaces in * classpath parameters * 13 src-jtulach1.12 5/17/99 Petr Hamernik fixed bug #1638 * 12 src-jtulach1.11 5/15/99 Jesse Glick [JavaDoc] * 11 src-jtulach1.10 5/7/99 Ales Novak getAllLibraries moved to * CompilationEngine * 10 src-jtulach1.9 5/6/99 Jan Jancura Bug when lib folder do * not exists. * 9 src-jtulach1.8 4/26/99 Jesse Glick [JavaDoc] * 8 src-jtulach1.7 4/22/99 Ales Novak utility methods added * 7 src-jtulach1.6 4/21/99 Jesse Glick [JavaDoc] * 6 src-jtulach1.5 4/21/99 Ales Novak method for parsing * commandline added * 5 src-jtulach1.4 4/16/99 Ales Novak * 4 src-jtulach1.3 3/29/99 Jesse Glick [JavaDoc] * 3 src-jtulach1.2 3/29/99 Ales Novak * 2 src-jtulach1.1 3/23/99 Jesse Glick [JavaDoc] * 1 src-jtulach1.0 1/6/99 Jaroslav Tulach * $ */